package xyz.labmem.app.unit

import javafx.animation.KeyFrame
import javafx.animation.KeyValue
import javafx.animation.Timeline
import javafx.beans.property.SimpleBooleanProperty
import javafx.event.EventHandler
import javafx.geometry.Insets
import javafx.geometry.Pos
import javafx.scene.control.ScrollPane
import javafx.scene.image.ImageView
import javafx.scene.layout.AnchorPane
import javafx.scene.layout.Pane
import javafx.scene.layout.VBox
import javafx.scene.paint.Color
import javafx.scene.shape.*
import javafx.util.Duration
import xyz.labmem.app.config.AppConfig.mouseImage
import xyz.labmem.app.config.AppConfig.uiImage
import xyz.labmem.app.main.MainStage
import xyz.labmem.app.util.mouseClickedPoll
import xyz.labmem.lipx.core.Type
import xyz.labmem.lipx.core.context.AppContext
import xyz.labmem.lipx.core.util.ClientConfigDataUtil
import xyz.labmem.util.viewRun


class GroupListUnit(private val parent_: ProxyListUnit) : AnchorPane() {

    private val bubble = Path()

    private val dataList = VBox()
    private var checkBtn = ""
    private var checkBtnType: Type? = null
    private val rect = Rectangle(.0, .0)
    private val width = 200.0
    private val vBoxWidth = 180.0
    private val timeline = Timeline()
    private var y: Double = .0
    private var type: Type = Type.FORWARD
    private val renderingTimeline = Timeline()

    init {
        clip = rect
        prefWidth = width
        prefHeightProperty().bind(parent_.prefHeightProperty())
        rect.heightProperty().bind(parent_.prefHeightProperty())
        children.add(bubble)
        dataList.alignment = Pos.CENTER
        children.add(ScrollPane(dataList).apply {
            layoutY = 28.0
            layoutX = 10.0
            prefWidth = vBoxWidth
            rotate = -3.0
            isFitToWidth = true
            hbarPolicy = ScrollPane.ScrollBarPolicy.NEVER
            prefHeightProperty().bind(this@GroupListUnit.prefHeightProperty().subtract(50))
        })
        renderingTimeline.onFinished = EventHandler {
            refresh()
        }
    }

    private fun makeBubble(y: Double) {
        bubble.elements.clear()
        bubble.fill = Color.BLACK
        bubble.stroke = Color.WHITE
        bubble.strokeWidth = 5.0
        bubble.opacity = .7
        bubble.elements.addAll(
            MoveTo(5.0, y),
            LineTo(15.0, 35.0),
            LineTo(180.0, 15.0),
            LineTo(200.0, prefHeight - 20),
            LineTo(35.0, prefHeight - 30),
            LineTo(5.0, y),
        )
    }

    fun showList(y: Double, type: Type) {
        this.y = y
        this.type = type
        rendering()
    }

    private fun onCheckBtnClick(it: GroupListBtn, type: Type) {
        it.check.value = true
        dataList.children.forEach { b ->
            if (b is GroupListBtn && b != it)
                b.check.value = false
        }
        //分组按钮点击
        val filter =
            AppContext.Client.allList.values.filter { c -> c.group == it.text && c.type == type }
        parent_.data.value.setAll(filter)
    }

    private fun rendering() {
        dataList.children.clear()
        timeline.stop()
        rect.width = -100.0
        renderingTimeline.keyFrames.setAll(KeyFrame(Duration.millis(300.0), KeyValue(rect.widthProperty(), 500)))
        renderingTimeline.play()
    }

    fun refresh() {
        dataList.children.clear()
        makeBubble(y)
        var i = 0
        Thread {
            ClientConfigDataUtil.refreshList()
            val data = if (type == Type.FORWARD) AppContext.Client.groupFList else AppContext.Client.groupRList
            timeline.keyFrames.setAll(
                KeyFrame(Duration.seconds(.05), { _ ->
                    if (i < data.size) {
                        val btn = GroupListBtn(data[i]) {
                            checkBtn = it.text
                            checkBtnType = type
                            onCheckBtnClick(it, type)
                        }
                        dataList.children.add(btn)
                        if (checkBtn == data[i] && type == checkBtnType) {
                            onCheckBtnClick(btn, type)
                        }
                        i++
                    } else
                        timeline.stop()
                }),
            )

            timeline.cycleCount = Timeline.INDEFINITE
            viewRun {
                timeline.play()
            }
        }.start()
    }
}

class GroupListBtn(var text: String, checkFun: (GroupListBtn) -> Unit) : Pane() {
    val checkFlag = ImageView(uiImage["m4"])
    val check = SimpleBooleanProperty(false)

    init {
        val labelUnit = LabelUnit(
            text, 20.0, maxStr = 7,
            clearance = 3.0,
            rotateS = -10.0,
            rotateE = 10.1,
            color = Color.WHITE,
            shadowColor = Color.TRANSPARENT,
            backColor = Color.WHITE,
            oColor = Color.BLACK
        )
        maxWidthProperty().bind(labelUnit.widthProperty())
        val action = Timeline(KeyFrame(Duration.millis(200.0), { _ -> labelUnit.refreshText() }))
        action.cycleCount = Timeline.INDEFINITE
        VBox.setMargin(this, Insets(10.0, .0, .0, .0))
        children.add(labelUnit)
        checkFlag.fitWidth = 35.0
        checkFlag.fitHeight = 35.0
        checkFlag.layoutXProperty().bind(widthProperty())
        checkFlag.isVisible = false
        children.add(checkFlag)
        onMouseClicked = mouseClickedPoll {
            checkFun(this)
        }
        onMouseEntered = EventHandler {
            MainStage.setCursor(mouseImage["m6"])
            action.play()
            labelUnit.style = "-fx-border-color: #ff0022; -fx-border-width: 0 0 2 0;"
        }
        onMouseExited = EventHandler {
            MainStage.cursorBack()
            action.stop()
            labelUnit.style = ""
        }
        check.addListener { _, _, v ->
            checkFlag.isVisible = v
        }
    }
}